package dwetl.transformer;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import dwetl.model.DimTable;
import dwetl.model.FactColumn;
import dwetl.model.FactTable;

@Scope("prototype")
@Service
public class FactTableTransformer extends DimMdfTalbeTransformer{
    private static final Logger logger = LoggerFactory.getLogger(FactTableTransformer.class);
    
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Transactional
    public Number doTransform(FactTable factTable , Map<String,Object> rowMap){
        Map<String,Map<String,Object>> ctxMap=new HashMap<String,Map<String,Object>>();

        List<DimTable> dimTables = factTable.getDimTables();
        for(DimTable dt:dimTables){
            putDimTable(dt,rowMap,ctxMap);
        }
        return putFactTable(factTable,rowMap,ctxMap);
    }

    Number putFactTable(FactTable ft,Map<String,Object> rowMap,Map<String,Map<String,Object>> ctxMap){
        String table=ft.getTable_name();
        List<String> insCols=new LinkedList<String>();
        List<String> wenhaos=new LinkedList<String>();
        List<Object> insColObjs=new LinkedList<Object>();
        for(FactColumn fc:ft.getEtl_columns()){
            if(fc.getIs_auto_id()){
                continue;
            }
            String tblCol=fc.getCol();
            insCols.add(fc.getCol());
            wenhaos.add("?");
            String srcCol=fc.getSrc_col();
            if(null==fc.getDim_id_from() || fc.getDim_id_from().length()==0){//没有设置dim_id_from
                insColObjs.add(fc.valTransform(rowMap.get(srcCol)));
            }else{//有设置dim_id_from从维表拿
                String dimTbl=fc.getDim_id_from().split("\\.")[0];
                String dimTblCol=fc.getDim_id_from().split("\\.")[1];
                Map m=ctxMap.get(dimTbl);
                if(m==null){
                    throw new RuntimeException(fc.getDim_id_from()+" dimTable may not found.");
                }
                Object val=ctxMap.get(dimTbl).get(dimTblCol);
                insColObjs.add(val);
            }
        }
        String insColStr=String.join(",",insCols);
        String wenhaoStr=String.join(",",wenhaos);
        String sql=String.format("insert into %s (%s) values (%s)",table,insColStr,wenhaoStr);
        logger.info("insert sql:"+sql);
        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update( new PreparedStatementCreator(){
            @Override
            public PreparedStatement createPreparedStatement(Connection conn) throws SQLException {
                PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);

                for(int i=0;i<insColObjs.size();i++) {
                    Object val = insColObjs.get(i);
                    if(val==null){
                        ps.setObject(i+1,null);
                    }else if(val instanceof java.util.Date){
                        java.sql.Timestamp dvl=new java.sql.Timestamp(((java.util.Date) val).getTime());
                        ps.setTimestamp(i + 1,dvl);
                    }else if (val instanceof java.sql.Date) {
                        ps.setTimestamp(i + 1, new java.sql.Timestamp(((java.sql.Date)val).getTime()));
                    }else{
                        ps.setString(1+i,""+val);
                    }
                }
                return ps;
            }
        },keyHolder);
        Number autoid= keyHolder.getKey();

        //put ctxMap
        Map<String,Object> tblMap=new HashMap<String,Object>();
        for(int i=0;i<insCols.size();i++){
            String key=insCols.get(i);
            Object val=insColObjs.get(i);
            tblMap.put(key,val);
        }
//        tblMap.put(autoIdCol,autoid);
        ctxMap.put(table,tblMap);
        return autoid;
    }

}
